/*
 * ==============================================================================
 * ||                  TikTok API 响应“手动美化输出”脚本                        ||
 * ==============================================================================
 *
 * 策略:
 * 1. 放弃 Gson，避免因混淆导致的崩溃。
 * 2. 编写一个'safeFormatObject'函数，通过安全的 Java 反射来遍历对象。
 * 3. 在遍历的同时，手动添加花括号、缩进和逗号，模拟出格式化的 JSON 效果。
 *    这样输出到文本文件后，结构清晰，易于阅读和分析。
 *
 */

console.log("====== “手动美化输出”脚本已部署，准备进行最终捕获... ======");

Java.perform(function() {
    console.log("====== Java.perform() 已执行，Hook 已就位。 ======");

    const SsResponse = Java.use("X.DBo");

    // 一个辅助函数，用于安全地、递归地将一个对象格式化为伪 JSON 字符串
    function safeFormatObject(obj, indent = "  ", visited = new Set()) {
        if (obj === null) {
            return "null";
        }
        if (obj === undefined) {
            return "undefined";
        }

        // 处理基本类型和字符串
        const obj_class = obj.getClass();
        if (obj_class.isPrimitive() || obj_class.getName().startsWith("java.lang")) {
            // 对字符串加上引号
            if (obj_class.getName() === "java.lang.String") {
                return `"${obj.toString()}"`;
            }
            return obj.toString();
        }

        // 处理循环引用，防止无限递归
        if (visited.has(obj)) {
            return `"[Circular Reference to ${obj.$className}]"`;
        }
        visited.add(obj);

        let output = "";
        
        // 处理数组
        if (obj_class.isArray()) {
            output += "[\n";
            const len = Java.array('java.lang.Object', obj).length;
            for(let i=0; i<len; i++){
                output += indent + "  " + safeFormatObject(obj[i], indent + "  ", visited);
                if(i < len -1) output += ",";
                output += "\n";
            }
            output += indent + "]";
            return output;
        }

        // 处理其他对象 (POJO)
        try {
            const fields = obj_class.getDeclaredFields();
            output += "{\n";
            
            for (let i = 0; i < fields.length; i++) {
                const field = fields[i];
                field.setAccessible(true);
                const fieldName = field.getName();
                const fieldValue = field.get(obj);
                
                output += `${indent}  "${fieldName}": ${safeFormatObject(fieldValue, indent + "  ", visited)}`;
                
                if (i < fields.length - 1) {
                    output += ",";
                }
                output += "\n";
            }
            
            output += indent + "}";
            return output;

        } catch (e) {
            // 如果反射失败，回退到 .toString()
            return `"[Inspect Error: ${e.message}] -> ${obj.toString()}"`;
        }
    }


    // Hook 创建成功响应的静态工厂方法
    SsResponse.LIZLLL.implementation = function(responseBody, rawResponse) {
        
        const result = this.LIZLLL(responseBody, rawResponse);

        try {
            let url = "[URL not found or failed to read]";
            if (rawResponse && rawResponse.LIZ && rawResponse.LIZ.value) {
                url = rawResponse.LIZ.value;
            }
            
            console.log("\n\n\n" + "======================================================");
            console.log("             >>> API Response Intercepted <<<             ");
            console.log("------------------------------------------------------");
            console.log("[*] URL: " + url);
            console.log("------------------------------------------------------");

            if (responseBody) {
                console.log("[+] Response Body (Formatted):");
                // 使用我们自定义的安全格式化函数
                console.log(safeFormatObject(responseBody));
            } else {
                console.log("[-] Response Body is null.");
            }
            console.log("========================================================\n\n\n");

        } catch (e) {
            console.error("[!] Hook 逻辑执行出错: " + e);
        }

        return result;
    };

    console.log("[*] 安全美化 Hook 已激活: X.DBo.LIZLLL");
    console.log("[*] 正在监听所有成功的网络请求... 请在 App 中操作。");
});